# encoding:utf-8
# 6.1.2 函数的参数
# def add(num1,num2):
#     print (num1+num2)
# add(1,7)

# 6.2.2 函数文档
# def exchangeRate(dollar):
#     """美元->人民币
#     汇率暂定为6.5
#     """
#     return dollar * 6.5
#
#
# print(exchangeRate(10))
# print(exchangeRate.__doc__)
# help(exchangeRate)

# 6.2.5 收集参数
# def test(*params):
#     print("有 %d 个参数" % len(params))
#     print("第二个参数是:", params[1])
#
#
# # test('F','i','s','h','C')
# a = [1, 2, 3, 4, 5, 6, 7, 8]
# test(*a)

# 6.3.1 函数和过程
# def hello():
#     print("Hello~")
#
#
# print(hello())

# 6.3.2 再谈返回值
# python 可以动态确定函数的类型，而且函数还能返回不同类型的值，pyton没有变量，只有名字
# 列表打包多种类型的值一次性返回
# def test():
#     return [1, '小甲鱼', 3.14]
#
#
# print(test())

# 也可以直接用元组的形式返回多个值
# def test():
#     return 1, '小甲鱼', 3.14
#
#
# print(test())

# 6.3.3 函数变量的作用域
# def discounts(price, rate):
#     final_price = price * rate
#     return final_price
#
#
# old_price = float(input('请输入原价：'))
# rate = float(input("请输入折扣率："))
# new_price = discounts(old_price, rate)
# print('打折后的价格是：', new_price)

# 6.4 内嵌函数和闭包
# global 关键字
# count = 5
#
#
# def myFun():
#     count = 10
#     print(count)
#
#
# myFun()
# print(count)

# count = 5
#
#
# def myFun():
#     global count
#     count = 10
#     print(count)
#
#
# myFun()
# print(count)

# 6.4.2 内嵌函数
# fun2()整个函数作用域在外部函数之内
# def fun1():
#     print("fun1()正在被调用...")
#
#     def fun2():
#         print("fun2()正在被调用...")
#
#     fun2()
#
#
# fun1()

# 6.4.3 闭包（closure）LISP语言（主要用于绘图和人工智能）
# 在一个内部函数里，对在外部作用域（但不在全局作用域）的变量进行引用，那么内部函数就被认为是闭包
# def funX(x):
#     def funY(y):
#         return x * y
# 
#     return funY
# 
# 
# i=funX(8)
# print (i(5))

# print (funX(8)(5))
# 注：在内部函数中，只能对外部函数的局部变量进行访问，但不能进行修改

# 容器类型
# def funX():
#     x = [5]
#
#     def funY():
#         x[0] *= x[0]
#         return x[0]
#
#     return funY
#
#
# print (funX()())

# nonlocal 在内部函数里修改外部函数里的局部变量的值
# def funX():
#     x = 5
#
#     def funY():
#         nonlocal x
#         x *= x
#         return x
#
#     return funY
#
#
# print(funX()())

# 6.5 lambda 表达式 匿名函数
# def ds(x):
#     return 2 * x + 1
#
#
# print(ds(5))

g = lambda x: 2 * x + 1
# print (g(5))

g = lambda x, y: x + y
# print (g(3,4))

# filter有两个参数。第一个参数可以是一个函数也可是None,
# 如果是一个函数的话，则将第二个可迭代数据里的每一个元素作为函数的参数进行计算
# 如果第一个参数为None，则直接将第二个参数中为True的值筛选出来
# help(filter)
temp = filter(None, [1, 0, False, True])


# print (list(temp))

# def odd(x):
#     return x % 2
#
#
# temp = filtedd, range(10))
# print (list(temp))

# print (list(filter(lambda x:x%2,range(10))))
# print (list(map(lambda x:x*2,range(10))))

# 6.6 递归
# import sys
#
# sys.setrecursionlimit(1000000)  # 将递归限制设置为100万层
#
#
# def recursion():
#     recursion()
#
#
# recursion()

# 非递归版
# def recursion(n):
#     result = n
#     for i in range(1, n):
#         result *= i
#     return result
#
#
# number = int(input('请输入一个整数：'))
# result = recursion(number)
# print("%d的阶乘是：%d" % (number, result))

# 递归版
# def factorial(n):
#     if n == 1:
#         return 1
#     else:
#         return n * factorial(n - 1)
#
#
# number = int(input('请输入一个整数：'))
# result = factorial(number)
# print("%d的阶乘是：%d" % (number, result))
# 递归每次函数调用都需要进行压栈、弹栈、保存和恢复寄存器的栈操作，非常消耗时间和空间

# 斐波纳契
# 迭代
# def fab(n):
#     a1 = 1
#     a2 = 1
#     a3 = 1
#     if n < 1:
#         print('输入有误！')
#         return -1
#     while (n - 2) > 0:
#         a3 = a1 + a2
#         a1 = a2
#         a2 = a3
#         n -= 1
#     return a3
#
#
# result = fab(35)
# if result != -1:
#     print('总共有%d对小兔崽子诞生！' % result)


# 递归
# def fab(n):
#     if n < 1:
#         print('输入有误！')
#         return -1
#     if n == 1 or n == 2:
#         return 1
#     else:
#         return fab(n - 1) + fab(n - 2)
#
#
# result = fab(35)
# if result != -1:
#     print('总共有%d对小兔崽子诞生！' % result)


# 汉诺塔
# def hanoi(n, x, y, z):
#     if n == 1:
#         print(x, '-->', z)  # 如果只有一层，直接从x移动到z
#     else:
#         hanoi(n - 1, x, y, z)  # 将前n-1个盘子从X移动到Y上
#         print(x, '-->', z)  # 将最底下的第64个盘子从X移动到Z上
#         hanoi(n - 1, y, x, z)  # 将Y上的63个盘子移动到Z上
#
#
# n = int(input('请输入汉诺塔的层数：'))
# hanoi(n, 'X', 'Y', 'Z')

